package com.wrupple.muba.catalogs.client.activity.process.state.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.google.gwt.event.shared.EventBus;
import com.google.inject.Inject;
import com.wrupple.muba.catalogs.client.activity.process.CatalogSelectionProcess;
import com.wrupple.muba.catalogs.client.activity.process.LoadSelectionProcessData;
import com.wrupple.muba.catalogs.client.cms.service.CatalogManagementSystem;
import com.wrupple.muba.catalogs.domain.CatalogEntry;
import com.wrupple.muba.catalogs.domain.CatalogProcessDescriptor;
import com.wrupple.muba.catalogs.domain.JsCatalogKey;
import com.wrupple.muba.common.client.JSOHelper;
import com.wrupple.muba.common.client.application.DataCallback;
import com.wrupple.muba.common.domain.FilterCriteria;
import com.wrupple.muba.common.domain.FilterData;
import com.wrupple.muba.common.shared.StateTransition;

public class LoadCatalogFilterCriteria implements LoadSelectionProcessData {
	
	static class CatalogSelectionCallback extends DataCallback<List<CatalogEntry>>{

		private StateTransition<CatalogProcessDescriptor> filterCallback;
		private CatalogProcessDescriptor processDescriptor;
		String targetField;
		private String criteriaValueField;
		public CatalogSelectionCallback(
				String targetField, String criteriaValueField, CatalogProcessDescriptor parameter, StateTransition<CatalogProcessDescriptor> onDone) {
			this.filterCallback = onDone;
			this.processDescriptor = parameter;
			this.targetField=targetField;
			this.criteriaValueField=criteriaValueField;
		}

		@Override
		public void execute() {
			if(result==null ||result.isEmpty()){
				filterCallback.setResultAndFinish(processDescriptor);
			}else{
				FilterData filter = processDescriptor.getFilterData();
				List<String> criteria = new ArrayList<String>(result.size());
				String criteriaValue ;
				for(CatalogEntry selection : result){
					criteriaValue = JSOHelper.getAttribute(selection, criteriaValueField);
					criteria.add(criteriaValue);
				}
				FilterCriteria filterCriteria = new FilterCriteria();
				filterCriteria.setOperator(FilterData.EQUALS);
				filterCriteria.setValues(criteria);
				filter.getFilters().put(targetField, Collections.singletonList(filterCriteria));
			}
		}
		
	}
	
	final CatalogManagementSystem cms;
	Context context;
	String catalog;
	String targetField;
	String criteriaValueField;
	
	@Inject
	public LoadCatalogFilterCriteria(CatalogManagementSystem cms) {
		super();
		this.cms = cms;
	}
	
	
	@Override
	public void start(CatalogProcessDescriptor parameter,
			StateTransition<CatalogProcessDescriptor> onDone, EventBus bus) {
		assert parameter!=null : "Catalog Process Descriptor must be previously loaded before filters are modified";
		assert catalog!=null;
		assert targetField!=null;
		FilterData currentFilter = parameter.getFilterData();
		if(currentFilter==null){
			currentFilter = new FilterData();
			parameter.setFilterData(currentFilter);
		}
		CatalogSelectionProcess<JsCatalogKey> selectionProcess = cms.getContentManager(catalog).getSelectionProcess(true);
		
		CatalogProcessDescriptor input = new CatalogProcessDescriptor();
		input.setFilterData(new FilterData());
		input.setSelectedType(catalog);
		
		StateTransition callback = new CatalogSelectionCallback(targetField,criteriaValueField,parameter,onDone);
		context.getProcessManager().processSwitch(selectionProcess, "FilterCriteriaSelection", input , callback, bus);
	}

	/**
	 * @param catalogid catalog to use for criteria selection
	 * @param criteriaValueField the field from which criteria values will be extracted
	 * @param tagerFilterField the field to filter
	 */
	public void initialize(String catalogid,String criteriaValueField,String tagerFilterField){
		this.catalog= catalogid;
		this.targetField = tagerFilterField;
		this.criteriaValueField = criteriaValueField;
	}

	
	@Override
	public void setContext(com.wrupple.muba.common.shared.State.Context context) {
		this.context=context;
	}
}
